package com.yang;

import com.yang.hander.ChatServerChannelInitializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;

/**
 * @Description: 聊天室的服务端代码
 * @author: Yang Qiang
 * @create: 2021-09-23 22:39
 */
@Slf4j
public class chatServer {
    // 服务的端口
    private int port = 8080;

    public static void main(String[] args) {
        chatServer server = new chatServer();
        server.start();
    }

    private void start(){
        start(this.port);
    }

    /**
     * 服务的的主代码
     * @param port
     */
    private void start(int port){
        // 主线程, 负责拿请求给从线程
        NioEventLoopGroup boos = new NioEventLoopGroup(1);
        // 从线程, 负责执行请求
        NioEventLoopGroup work = new NioEventLoopGroup();

        // 启动类: 相当于SpringBoot的application, 把所有东西组合在一起, 然后启动
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap
                // 加入线程
                .group(boos, work)
                // 使用NIO通信方式
                .channel(NioServerSocketChannel.class)
                // 设置阻塞队列和长度
                .option(ChannelOption.SO_BACKLOG, 1024)
                // 业务的处理, 我们把业务处理类抽取出去编写, 然后直接放进来就行了
                .childHandler(new ChatServerChannelInitializer());

        // 绑定端口, 异步过程, 成功就会返回future
        try {
            ChannelFuture future = bootstrap.bind(this.port).sync();
            log.info("服务已经启动, 监听端口:{}", this.port );
            // 等待关闭, 如果没有关闭, 那么主线程就一直在这里卡住, 保证主线程的存活
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            boos.shutdownGracefully();
            work.shutdownGracefully();
        }
    }
}
